home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / directx / dxf / samples / multimedia / common / src / diutil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  8.1 KB  |  281 lines

  1. //-----------------------------------------------------------------------------
  2. // File: DIUtil.cpp
  3. //
  4. // Desc: DirectInput framework class using semantic mapping.  Feel free to use 
  5. //       this class as a starting point for adding extra functionality.
  6. //
  7. // Copyright (C) 1995-2000 Microsoft Corporation. All Rights Reserved.
  8. //-----------------------------------------------------------------------------
  9. #define STRICT
  10. #include <basetsd.h>
  11. #include <tchar.h>
  12. #include <stdio.h>
  13. #include "DIUtil.h"
  14. #include "DXUtil.h"
  15.  
  16.  
  17.  
  18.  
  19.  
  20. //-----------------------------------------------------------------------------
  21. // Name:
  22. // Desc:
  23. //-----------------------------------------------------------------------------
  24. CInputDeviceManager::CInputDeviceManager()
  25. {
  26.     //call CoInitialize();
  27.     CoInitialize(NULL);
  28.  
  29.     m_dwNumDevices = 0;
  30.     m_pDI          = NULL;
  31. }
  32.  
  33.  
  34.  
  35.  
  36. //-----------------------------------------------------------------------------
  37. // Name:
  38. // Desc:
  39. //-----------------------------------------------------------------------------
  40. CInputDeviceManager::~CInputDeviceManager()
  41. {
  42.     // Release() all devices
  43.     for( DWORD i=0; i<m_dwNumDevices; i++ )
  44.     {
  45.         m_pdidDevices[i]->Unacquire();
  46.         m_pdidDevices[i]->Release();
  47.         m_pdidDevices[i] = NULL;
  48.     }
  49.  
  50.     // Release() base object
  51.     SAFE_RELEASE( m_pDI );
  52.  
  53.     //call CoUninitialize();
  54.     CoUninitialize();
  55. }
  56.  
  57.  
  58.  
  59.  
  60. //-----------------------------------------------------------------------------
  61. // Name:
  62. // Desc:
  63. //-----------------------------------------------------------------------------
  64. HRESULT CInputDeviceManager::GetDevices( LPDIRECTINPUTDEVICE8** ppDevice, 
  65.                                          DWORD* pdwCount )
  66. {
  67.     if( NULL==ppDevice || NULL==pdwCount )
  68.         return E_INVALIDARG;
  69.  
  70.     (*ppDevice) = m_pdidDevices;
  71.     (*pdwCount) = m_dwNumDevices;
  72.  
  73.     return S_OK;
  74. }
  75.  
  76.  
  77.  
  78.  
  79. //-----------------------------------------------------------------------------
  80. // Name:
  81. // Desc:
  82. //-----------------------------------------------------------------------------
  83. HRESULT CInputDeviceManager::AddDevice( const DIDEVICEINSTANCE* pdidi, 
  84.                                         const LPDIRECTINPUTDEVICE8 pdidDevice )
  85. {
  86.     HRESULT hr;
  87.     DWORD   dwDeviceType = pdidi->dwDevType;
  88.  
  89.     pdidDevice->Unacquire();
  90.  
  91.     // Set the device's coop level
  92.     if( GET_DIDEVICE_TYPE(dwDeviceType) == DI8DEVTYPE_MOUSE )
  93.         hr = pdidDevice->SetCooperativeLevel( m_hWnd, DISCL_EXCLUSIVE|DISCL_FOREGROUND );
  94.     else
  95.         hr = pdidDevice->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND );
  96.     if( FAILED(hr) )
  97.         return hr;
  98.  
  99.     // Set relative mode for mouse
  100.     if( GET_DIDEVICE_TYPE(dwDeviceType) == DI8DEVTYPE_MOUSE )
  101.     {
  102.         DIPROPDWORD dipdw;
  103.         dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
  104.         dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  105.         dipdw.diph.dwObj        = 0;
  106.         dipdw.diph.dwHow        = DIPH_DEVICE;
  107.         dipdw.dwData            = DIPROPAXISMODE_REL;
  108.         hr = pdidDevice->SetProperty( DIPROP_AXISMODE, &dipdw.diph );
  109.     }
  110.  
  111.     m_pdidDevices[m_dwNumDevices] = pdidDevice;
  112.     m_pdidDevices[m_dwNumDevices]->AddRef();
  113.  
  114.     hr = m_pdidDevices[m_dwNumDevices]->BuildActionMap( &m_diaf, m_strUserName, 0 );
  115.     hr = m_pdidDevices[m_dwNumDevices]->SetActionMap( &m_diaf, m_strUserName, 0 );
  116.  
  117.     m_dwNumDevices++;
  118.  
  119.     // Continue enumerating suitable devices
  120.     return S_OK;
  121. }
  122.  
  123.  
  124.  
  125.  
  126. //-----------------------------------------------------------------------------
  127. // Name:
  128. // Desc:
  129. //-----------------------------------------------------------------------------
  130. BOOL CALLBACK EnumSuitableDevicesCB( LPCDIDEVICEINSTANCE pdidi, 
  131.                                      LPDIRECTINPUTDEVICE8A pdidDevice, 
  132.                                      DWORD dwFlags, DWORD dwDeviceRemaining,
  133.                                      VOID* pContext )
  134. {
  135.     // Add the device to the device manager's internal list
  136.     ((CInputDeviceManager*)pContext)->AddDevice( pdidi, pdidDevice );
  137.  
  138.     // Continue enumerating suitable devices
  139.     return DIENUM_CONTINUE;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. //-----------------------------------------------------------------------------
  146. // Name:
  147. // Desc:
  148. //-----------------------------------------------------------------------------
  149. HRESULT CInputDeviceManager::SetActionFormat( DIACTIONFORMAT& diaf, BOOL bReenumerate )
  150. {
  151.     HRESULT hr = S_OK;
  152.  
  153.     // Store the new action format
  154.     m_diaf = diaf;
  155.  
  156.     // Only destroy and re-enumerate devices if the caller explicitly wants to. The 
  157.     // device list may be used within a loop, and kicking off an enumeration while 
  158.     // the device array is in use would cause problems.
  159.     if( bReenumerate )
  160.     {
  161.         // Cleanup any previously enumerated devices
  162.         for( DWORD i=0; i<m_dwNumDevices; i++ )
  163.         {
  164.             m_pdidDevices[i]->Unacquire();
  165.             m_pdidDevices[i]->Release();
  166.             m_pdidDevices[i] = NULL;
  167.         }
  168.         m_dwNumDevices = 0;
  169.  
  170.         // Enumerate suitable DirectInput devices
  171.         hr = m_pDI->EnumDevicesBySemantics( m_strUserName, &m_diaf, 
  172.                                             EnumSuitableDevicesCB, this, 0L );
  173.     }
  174.     else // Just apply the new maps.
  175.     {
  176.         // Devices must be unacquired to have a new action map set.
  177.         UnacquireDevices();
  178.  
  179.         // Apply the new action map to the current devices.
  180.         for( DWORD i=0; i<m_dwNumDevices; i++ )
  181.         {
  182.             m_pdidDevices[i]->BuildActionMap( &m_diaf, m_strUserName, 0 );
  183.             m_pdidDevices[i]->SetActionMap( &m_diaf, m_strUserName, 0 );
  184.         }
  185.     }
  186.  
  187.     if( FAILED(hr) )
  188.         return hr;
  189.  
  190.     return S_OK;
  191. }
  192.  
  193.  
  194.  
  195.  
  196. //-----------------------------------------------------------------------------
  197. // Name: Create()
  198. // Desc:
  199. //-----------------------------------------------------------------------------
  200. HRESULT CInputDeviceManager::Create( HWND hWnd, TCHAR* strUserName, 
  201.                                      DIACTIONFORMAT& diaf )
  202. {
  203.     HRESULT hr;
  204.  
  205.     // Store data
  206.     m_hWnd        = hWnd;
  207.     m_strUserName = strUserName;
  208.     
  209.     // Create the base DirectInput object
  210.     hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
  211.                               IID_IDirectInput8, (VOID**)&m_pDI, NULL );
  212.     if( FAILED(hr) )
  213.         return hr;
  214.  
  215.     SetActionFormat( diaf, TRUE );
  216.  
  217.     return S_OK;
  218. }
  219.  
  220.  
  221.  
  222.  
  223. //-----------------------------------------------------------------------------
  224. // Name: Create()
  225. // Desc:
  226. //-----------------------------------------------------------------------------
  227. HRESULT CInputDeviceManager::ConfigureDevices( HWND hWnd, IUnknown* pSurface,
  228.                                                VOID* ConfigureDevicesCB,
  229.                                                DWORD dwFlags )
  230. {
  231.     HRESULT hr;
  232.  
  233.     // Initialize all the colors here
  234.     DICOLORSET dics;
  235.     ZeroMemory(&dics, sizeof(DICOLORSET));
  236.     dics.dwSize = sizeof(DICOLORSET);
  237.  
  238.     // Fill in all the params
  239.     DICONFIGUREDEVICESPARAMS dicdp;
  240.     ZeroMemory(&dicdp, sizeof(dicdp));
  241.     dicdp.dwSize = sizeof(dicdp);
  242.     dicdp.dwcFormats     = 1;
  243.     dicdp.lprgFormats    = &m_diaf;
  244.     dicdp.hwnd           = hWnd;
  245.     dicdp.lpUnkDDSTarget = pSurface;
  246.  
  247.     if( m_strUserName )
  248.     {
  249.         dicdp.dwcUsers       = 1;
  250.         dicdp.lptszUserNames = m_strUserName;
  251.     }
  252.  
  253.     // Unacquire the devices so that mouse doesn't control the game while in control panel
  254.     UnacquireDevices();
  255.  
  256.     hr = m_pDI->ConfigureDevices( (LPDICONFIGUREDEVICESCALLBACK)ConfigureDevicesCB, 
  257.                                   &dicdp, dwFlags, NULL );
  258.  
  259.     if( dwFlags & DICD_EDIT )
  260.     {
  261.         // Re-set up the devices
  262.         hr = SetActionFormat( m_diaf, TRUE );
  263.     }
  264.  
  265.     return hr;
  266. }
  267.  
  268.  
  269.  
  270. //-----------------------------------------------------------------------------
  271. // Name: UnacquireDevices()
  272. // Desc:
  273. //-----------------------------------------------------------------------------
  274. VOID CInputDeviceManager::UnacquireDevices()
  275. {
  276.     for( DWORD i=0; i<m_dwNumDevices; i++ )
  277.         m_pdidDevices[i]->Unacquire();
  278. }
  279.  
  280.  
  281.